package lock

import (
	"context"
	"github.com/go-redis/redis/v8"
	"github.com/zhufuyi/sponge/pkg/logger"
	"shop/internal/model"
	"sync"
	"time"
)

var (
	singleton *RedisClient
	once      sync.Once
)

type RedisClient struct {
	Client *redis.Client
}

func newRedisClient() *RedisClient {
	logger.Info("redis初始化成功")
	Client := model.GetRedisCli()
	return &RedisClient{
		Client: Client,
	}
}

// TryLock 自动上锁
func (rl *RedisClient) TryLock(key string, value string, expiration time.Duration, fn func()) {
	result, err := rl.Client.SetNX(context.Background(), key, value, expiration).Result()
	if err != nil || !result {
		logger.Info("Failed to acquire lock:", logger.Err(err))
		return
	}

	defer rl.Client.Del(context.Background(), key)
	fn()
}

// AcquireLock 上锁
func (rl *RedisClient) AcquireLock(key string, value string, expiration time.Duration) (bool, error) {

	result, err := rl.Client.SetNX(context.Background(), key, value, expiration).Result()
	if err != nil {
		return false, err
	}
	return result, nil
}

// ReleaseLock 手动释放锁
func (rl *RedisClient) ReleaseLock(key string) error {
	return rl.Client.Del(context.Background(), key).Err()
}

func GetInstance() *RedisClient {
	once.Do(func() {
		singleton = newRedisClient()
	})
	return singleton
}

//usage
// 创建 RedisLock 实例
//redisLock := NewRedisLock("localhost:6379", "", 0)
//
//// 设置锁的键名和值
//lockKey := "my-lock"
//lockValue := "lock-value"
//
//// 获取锁
//acquired, err := redisLock.AcquireLock(lockKey, lockValue, 10*time.Second)
//if err != nil {
//fmt.Println("Failed to acquire lock:", err)
//return
//}
//
//if acquired {
//// 成功获取到锁，执行需要互斥访问的代码
//
//// 释放锁
//err := redisLock.ReleaseLock(lockKey)
//if err != nil {
//fmt.Println("Failed to release lock:", err)
//return
//}
//} else {
//// 获取锁失败，锁已被其他进程持有
//fmt.Println("Failed to acquire lock: lock already held by another process")
//return
//}
//
//fmt.Println("Lock released")
